package com.util.common;

import cn.hutool.core.bean.BeanUtil;
import com.exception.ServiceException;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.util.Map;

/**
 * @author zhangweiwei
 * @date 2020-07-30
 */
@Data
@ApiModel("统一返回视图")
public class R<T> {
    
    @ApiModelProperty("状态")
    private Integer code = RStatus.SUCCESS.getValue();
    
    @ApiModelProperty("消息")
    private String msg = RStatus.SUCCESS.getMessage();
    
    @ApiModelProperty("数据")
    private T data;
    
    public R(Integer code, String message, T data) {
        this.code = code;
        this.msg = message;
        this.data = data;
    }
    
    /**
     * 成功返回
     */
    public static <T> R<T> ok(String message, T data) {
        return new R<>(RStatus.SUCCESS.getValue(), message, data);
    }
    
    public static <T> R<T> ok(T data) {
        return new R<>(RStatus.SUCCESS.getValue(), "成功", data);
    }
    public static R ok(){
        return new R(RStatus.SUCCESS.getValue(),RStatus.SUCCESS.getMessage(),null);
    }
    /**
     * 返回的时候排除某些字段，针对单个对象有效，集合数组无效
     * @param data
     * @param excludes
     * @param <T>
     * @return
     */
    public static <T> R ok(T data,String[] excludes){
        Map<String,Object> map = BeanUtil.beanToMap(data);
        for(String s:excludes){
            map.remove(s);
        }
        return new R(RStatus.SUCCESS.getValue(),RStatus.SUCCESS.getMessage(),map);
    }

    public R(Throwable e) {
        this.msg = e.getMessage();
        if (e instanceof ServiceException) {
            this.code = ((ServiceException) e).getCode();
            this.data = (T) ((ServiceException) e).getData();
        } else {
            this.code = RStatus.FAIL.getValue();
        }
        
    }
    
    
    /**
     * 失败返回
     */
    public static <T> R<T> error(Integer state, String message, T data) {
        return new R<>(state, message, data);
    }
    
    public static <T> R<T> error(String message, T data) {
        return new R<>(RStatus.FAIL.getValue(), message, data);
    }
    
    public static <T> R<T> error(String message) {
        return new R<>(RStatus.FAIL.getValue(), message, null);
    }
    
    public static <T> R<T> error(T data) {
        return new R<>(RStatus.FAIL.getValue(), "", data);
    }
}
